﻿#include "curlUpload.h"
#include "curlUtils.h"
#include <mutex>

// 定义全局变量
namespace HNNetwork {

    std::mutex uploadMtx; // 互斥锁，用于保护全局变量
    
    // 获取已上传的文件大小（通过HTTP HEAD请求获取服务器上对应资源的Content-Length）
    long getUploadSize(const char* url)
    {
        CURL* curl = curl_easy_init();
        if (curl)
        {
            CURLcode res = curl_easy_setopt(curl, CURLOPT_URL, url);
            res = curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); // 设置为HEAD请求，不返回body内容
            res = curl_easy_perform(curl);
            if (res == CURLE_OK)
            {
                long contentLength;
                res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &contentLength); // 获取Content-Length头部信息
                curl_easy_cleanup(curl);
                return contentLength;
            }

            curl_easy_cleanup(curl);
        }

        return 0;
    }

    // 每个线程执行的函数体，用于上传指定范围的数据块
    void uploadChunk(long uploadedSize, const char* url, long start, long end, long threadID)
    {

        curl_off_t rangeStart = start;
        curl_off_t rangeEnd = end;

        std::string headerRange = std::string("Range: bytes=").append(std::to_string(rangeStart)).append("-").append(std::to_string(rangeEnd));

        CURL* curl = curl_easy_init();
        if (curl)
        {
            uploadFile.seekg(start);

            curl_easy_setopt(curl, CURLOPT_URL, url);
            curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); // 设置为上传请求
            curl_easy_setopt(curl, CURLOPT_READDATA, &uploadFile);
            curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, CHUNK_SIZE);
            curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL); // 不需要返回body内容

            struct curl_slist* headerList = NULL;
            headerList = curl_slist_append(headerList, headerRange.c_str());

            // 添加断点续传的相关选项
            if (threadID > 0)
                curl_easy_setopt(curl, CURLOPT_RESUME_FROM_LARGE, uploadedSize + start);

            // 设置HTTP头部信息
            curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerList);

            // 执行上传请求
            CURLcode res = curl_easy_perform(curl);
            MessageCallbackThread(url, threadID, res, curl_easy_strerror(res));
            // 释放资源
            curl_slist_free_all(headerList);
            curl_easy_cleanup(curl);
        }
    }
}//HNNetWork
